//16 个 clock 接收一个 bit，16 个时钟采样，取中间的采样值
module RXD(clk,bps_clk,rst, rx,dataout [7:0], rdsig,idle, dataerror, frameerror,R);
input clk;					//系统时钟
input rst;					//复位信号
input bps_clk;				//波特率
output rx;					//uart数据输入
output [7:0] dataout;	//接收数据输出
output rdsig;				//接收信号标志
output dataerror;			//数据出错指示
output frameerror;		//帧出错指示
output R;					//接收完成且数据无错，标志位
output idle;
reg [7:0] dataout;		
reg rdsig,dataerror,frameerror;
reg [7:0] cnt;
reg rxbuf,rxfall,receive;
parameter paritymode =1'b0;
reg presult;				//奇偶标志位		
reg idle;					//空闲标志位
reg r1,r2;
reg R;
//检测电路下降沿
always @(posedge clk)
begin
	rxbuf<=rx;
	rxfall<=rxbuf&(~rx);
end

//////////////////////////////
//启动串口接收程序
/////////////////////////////
always @(posedge clk)
begin//检测到线路的下降沿并且原先线路为空闲，启动接收数据进程
	if(rxfall &&(~idle))
	begin
		receive<=1'b1;
	end
	else if(cnt ==8'd168)//接收数据完成
	begin
		receive<=1'b0;
	end
end
//////////
//判断接收完成,且无错
always@(posedge clk)
begin
	r1<=receive;
	r2<=r1;
	if(r2&(!r1)&(!dataerror)&(!frameerror))
	R<=1'd1;
end
////////////////////////////////////
//串口接收程序, 16 个系统时钟接收一个 bit
///////////////////////////////////
always @(posedge clk or negedge rst)
begin
	if(!rst)
	begin
		idle<=1'b0;
		cnt<=8'd0;
		rdsig<=1'b0;
		frameerror<=1'b0;
		dataerror<=1'b0;
		presult<=1'b0;
	end
	else if(receive ==1'b1)
	begin
		case(cnt)
		8'd0:begin
				idle<=1'b1;
				cnt<=cnt+8'd1;
				rdsig<=1'b0;
		end
		8'd24,8'd40,8'd56,8'd72,8'd88,8'd104,8'd120,8'd136:
		if(bps_clk)begin		 //接收第0~7位数据
				idle<=1'b1;
				dataout[(cnt/16)-1]<=rx;
				presult<=paritymode^rx;
				cnt<=cnt+8'd1;
				rdsig<=1'b0;
		end
		
		8'd152:if(bps_clk)begin		 //接收奇偶校验位
				idle<=1'b1;
				if(presult ==rx)
					dataerror<=1'b0;
				else
					dataerror<=1'b1;//如果奇偶校验位不对，表示数据出错
				cnt<=cnt+8'd1;
				rdsig<=1'b0;
		end
		8'd168:begin
			idle<=1'b1;
			if(1'b1 ==rx)
				frameerror<=1'b0;
			else
				frameerror<=1'b1;//如果没有接收到停止位，表示帧出错
			cnt<=cnt+8'd1;
			rdsig<=1'b1;
		end
		endcase
	end
	else
	begin
		cnt<=8'd0;
		idle<=1'b0;
		rdsig<=1'b0;
	end
	
end

endmodule
